package com.dandelion.common.wx;

import com.dandelion.common.domain.WxUser;
import com.fasterxml.jackson.databind.JsonNode;
import com.rockit.core.exception.BadCredentialsException;
import com.rockit.core.exception.InvalidAccessTokenException;
import com.rockit.core.exception.NetworkErrorException;
import com.rockit.core.http.HttpClientService;
import com.rockit.core.http.HttpRequest;
import com.rockit.core.http.HttpResponse;
import com.rockit.core.http.HttpRuntimeException;
import com.rockit.core.utils.JacksonUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class WxLoginService {
    private static final Logger logger = LoggerFactory.getLogger(WxLoginService.class);

    @Autowired
    private HttpClientService httpService;

    @Autowired
    private WxConfigProperties wxConfigProperties;

    public WxUser login(String jsCode) throws InvalidAccessTokenException, NetworkErrorException, BadCredentialsException {
        HttpRequest request = HttpRequest.get(wxConfigProperties.getUrl());
        request.addUrlParameter("appid", wxConfigProperties.getAppId());
        request.addUrlParameter("secret", wxConfigProperties.getAppSecret());
        request.addUrlParameter("js_code", jsCode);
        request.addUrlParameter("grant_type", "authorization_code");

        HttpResponse response = null;
        try {
            response = httpService.execute(request);
            JsonNode node = JacksonUtil.toJsonNode(response.getBody());
            if (logger.isDebugEnabled()) {
                logger.debug("weixin login result:{}", response.getBody());
            }

            if (node != null) {
                WxUser user = JacksonUtil.toObject(node, WxUser.class);
                if (user != null && StringUtils.isNotBlank(user.getOpenid())) {
                    return user;
                }
            }
        } catch (HttpRuntimeException e) {
            logger.error("weixin login error", e);
            throw new NetworkErrorException();
        } catch (Exception e) {
            logger.error("weixin login error, js_code:{}, response:{}", jsCode, response == null ? null : response.getBody(), e);
            throw new BadCredentialsException();
        }
        logger.error("weixin login failed, js_code:{}, response:{}", jsCode, response == null ? null : response.getBody());
        throw new InvalidAccessTokenException();
    }
}
